home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / lynx-2.4 / WWW / Library / Implementation / HTUU.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-28  |  7.3 KB  |  208 lines

  1.  
  2. /* MODULE                            HTUU.c
  3. **            UUENCODE AND UUDECODE
  4. **
  5. ** ACKNOWLEDGEMENT:
  6. **    This code is taken from rpem distribution, and was originally
  7. **    written by Mark Riordan.
  8. **
  9. ** AUTHORS:
  10. **    MR    Mark Riordan    riordanmr@clvax1.cl.msu.edu
  11. **    AL    Ari Luotonen    luotonen@dxcern.cern.ch
  12. **
  13. ** HISTORY:
  14. **    Added as part of the WWW library and edited to conform
  15. **    with the WWW project coding standards by:    AL  5 Aug 1993
  16. **    Originally written by:                MR 12 Aug 1990
  17. **    Original header text:
  18. ** -------------------------------------------------------------
  19. **  File containing routines to convert a buffer
  20. **  of bytes to/from RFC 1113 printable encoding format.
  21. **
  22. **  This technique is similar to the familiar Unix uuencode
  23. **  format in that it maps 6 binary bits to one ASCII
  24. **  character (or more aptly, 3 binary bytes to 4 ASCII
  25. **  characters).  However, RFC 1113 does not use the same
  26. **  mapping to printable characters as uuencode.
  27. **
  28. **  Mark Riordan   12 August 1990 and 17 Feb 1991.
  29. **  This code is hereby placed in the public domain.
  30. ** -------------------------------------------------------------
  31. **
  32. ** BUGS:
  33. **
  34. **
  35. */
  36.  
  37. #include "HTUtils.h"
  38. #include "HTUU.h"
  39.  
  40. #include "LYLeaks.h"
  41.  
  42. PRIVATE char six2pr[64] = {
  43.     'A','B','C','D','E','F','G','H','I','J','K','L','M',
  44.     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  45.     'a','b','c','d','e','f','g','h','i','j','k','l','m',
  46.     'n','o','p','q','r','s','t','u','v','w','x','y','z',
  47.     '0','1','2','3','4','5','6','7','8','9','+','/'
  48. };
  49.  
  50. PRIVATE unsigned char pr2six[256];
  51.  
  52.  
  53. /*--- function HTUU_encode -----------------------------------------------
  54.  *
  55.  *   Encode a single line of binary data to a standard format that
  56.  *   uses only printing ASCII characters (but takes up 33% more bytes).
  57.  *
  58.  *    Entry    bufin    points to a buffer of bytes.  If nbytes is not
  59.  *                      a multiple of three, then the byte just beyond
  60.  *                      the last byte in the buffer must be 0.
  61.  *             nbytes   is the number of bytes in that buffer.
  62.  *                      This cannot be more than 48.
  63.  *             bufcoded points to an output buffer.  Be sure that this
  64.  *                      can hold at least 1 + (4*nbytes)/3 characters.
  65.  *
  66.  *    Exit     bufcoded contains the coded line.  The first 4*nbytes/3 bytes
  67.  *                      contain printing ASCII characters representing
  68.  *                      those binary bytes. This may include one or
  69.  *                      two '=' characters used as padding at the end.
  70.  *                      The last byte is a zero byte.
  71.  *             Returns the number of ASCII characters in "bufcoded".
  72.  */
  73. PUBLIC int HTUU_encode ARGS3(unsigned char *,    bufin,
  74.                  unsigned int,    nbytes,
  75.                  char *,        bufcoded)
  76. {
  77. /* ENC is the basic 1 character encoding function to make a char printing */
  78. #define ENC(c) six2pr[c]
  79.  
  80.    register char *outptr = bufcoded;
  81.    unsigned int i;
  82.    /* This doesn't seem to be needed (AL):   register unsigned char *inptr  = bufin; */
  83.  
  84.    for (i=0; i<nbytes; i += 3) {
  85.       *(outptr++) = ENC(*bufin >> 2);            /* c1 */
  86.       *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
  87.       *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03));/*c3*/
  88.       *(outptr++) = ENC(bufin[2] & 077);         /* c4 */
  89.  
  90.       bufin += 3;
  91.    }
  92.  
  93.    /* If nbytes was not a multiple of 3, then we have encoded too
  94.     * many characters.  Adjust appropriately.
  95.     */
  96.    if(i == nbytes+1) {
  97.       /* There were only 2 bytes in that last group */
  98.       outptr[-1] = '=';
  99.    } else if(i == nbytes+2) {
  100.       /* There was only 1 byte in that last group */
  101.       outptr[-1] = '=';
  102.       outptr[-2] = '=';
  103.    }
  104.    *outptr = '\0';
  105.    return(outptr - bufcoded);
  106. }
  107.  
  108.  
  109. /*--- function HTUU_decode ------------------------------------------------
  110.  *
  111.  *  Decode an ASCII-encoded buffer back to its original binary form.
  112.  *
  113.  *    Entry    bufcoded    points to a uuencoded string.  It is 
  114.  *                         terminated by any character not in
  115.  *                         the printable character table six2pr, but
  116.  *                         leading whitespace is stripped.
  117.  *             bufplain    points to the output buffer; must be big
  118.  *                         enough to hold the decoded string (generally
  119.  *                         shorter than the encoded string) plus
  120.  *                         as many as two extra bytes used during
  121.  *                         the decoding process.
  122.  *             outbufsize  is the maximum number of bytes that
  123.  *                         can fit in bufplain.
  124.  *
  125.  *    Exit     Returns the number of binary bytes decoded.
  126.  *             bufplain    contains these bytes.
  127.  */
  128. PUBLIC int HTUU_decode ARGS3(char *,        bufcoded,
  129.                  unsigned char *,    bufplain,
  130.                  int,        outbufsize)
  131. {
  132. /* single character decode */
  133. #define DEC(c) pr2six[c]
  134. #define MAXVAL 63
  135.  
  136.    static int first = 1;
  137.  
  138.    int nbytesdecoded, j;
  139.    register char *bufin = bufcoded;
  140.    register unsigned char *bufout = bufplain;
  141.    register int nprbytes;
  142.  
  143.    /* If this is the first call, initialize the mapping table.
  144.     * This code should work even on non-ASCII machines.
  145.     */
  146.    if(first) {
  147.       first = 0;
  148.       for(j=0; j<256; j++) pr2six[j] = MAXVAL+1;
  149.  
  150.       for(j=0; j<64; j++) pr2six[six2pr[j]] = (unsigned char) j;
  151. #if 0
  152.       pr2six['A']= 0; pr2six['B']= 1; pr2six['C']= 2; pr2six['D']= 3; 
  153.       pr2six['E']= 4; pr2six['F']= 5; pr2six['G']= 6; pr2six['H']= 7; 
  154.       pr2six['I']= 8; pr2six['J']= 9; pr2six['K']=10; pr2six['L']=11; 
  155.       pr2six['M']=12; pr2six['N']=13; pr2six['O']=14; pr2six['P']=15; 
  156.       pr2six['Q']=16; pr2six['R']=17; pr2six['S']=18; pr2six['T']=19; 
  157.       pr2six['U']=20; pr2six['V']=21; pr2six['W']=22; pr2six['X']=23; 
  158.       pr2six['Y']=24; pr2six['Z']=25; pr2six['a']=26; pr2six['b']=27; 
  159.       pr2six['c']=28; pr2six['d']=29; pr2six['e']=30; pr2six['f']=31; 
  160.       pr2six['g']=32; pr2six['h']=33; pr2six['i']=34; pr2six['j']=35; 
  161.       pr2six['k']=36; pr2six['l']=37; pr2six['m']=38; pr2six['n']=39; 
  162.       pr2six['o']=40; pr2six['p']=41; pr2six['q']=42; pr2six['r']=43; 
  163.       pr2six['s']=44; pr2six['t']=45; pr2six['u']=46; pr2six['v']=47; 
  164.       pr2six['w']=48; pr2six['x']=49; pr2six['y']=50; pr2six['z']=51; 
  165.       pr2six['0']=52; pr2six['1']=53; pr2six['2']=54; pr2six['3']=55; 
  166.       pr2six['4']=56; pr2six['5']=57; pr2six['6']=58; pr2six['7']=59; 
  167.       pr2six['8']=60; pr2six['9']=61; pr2six['+']=62; pr2six['/']=63;
  168. #endif
  169.    }
  170.  
  171.    /* Strip leading whitespace. */
  172.  
  173.    while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
  174.  
  175.    /* Figure out how many characters are in the input buffer.
  176.     * If this would decode into more bytes than would fit into
  177.     * the output buffer, adjust the number of input bytes downwards.
  178.     */
  179.    bufin = bufcoded;
  180.    while(pr2six[*(bufin++)] <= MAXVAL);
  181.    nprbytes = bufin - bufcoded - 1;
  182.    nbytesdecoded = ((nprbytes+3)/4) * 3;
  183.    if(nbytesdecoded > outbufsize) {
  184.       nprbytes = (outbufsize*4)/3;
  185.    }
  186.  
  187.    bufin = bufcoded;
  188.    
  189.    while (nprbytes > 0) {
  190.       *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
  191.       *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
  192.       *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
  193.       bufin += 4;
  194.       nprbytes -= 4;
  195.    }
  196.    
  197.    if(nprbytes & 03) {
  198.       if(pr2six[bufin[-2]] > MAXVAL) {
  199.          nbytesdecoded -= 2;
  200.       } else {
  201.          nbytesdecoded -= 1;
  202.       }
  203.    }
  204.  
  205.    return(nbytesdecoded);
  206. }
  207.  
  208.